﻿using IOP.SgrA;
using IOP.SgrA.SilkNet.Vulkan;
using Microsoft.Extensions.Logging;
using Silk.NET.Vulkan;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace VkSample41
{
    public class WindowConfig : IWindowConfig<Window, VulkanGraphicsManager>
    {
        public Task Config(Window window, VulkanGraphicsManager graphics)
        {
            try
            {
                var windowOption = window.Option;
                var lDevice = graphics.VulkanDevice;
                var swapchain = lDevice.CreateDefaultSwapChain(window).CreateDefaultSwapChainImageViews();
                VulkanImageView dImage = lDevice.CreateDepthBuffer((device, option) =>
                {
                    var props = device.GetFormatProperties(Format.D16Unorm);
                    option.Format = Format.D16Unorm;
                    option.ImageType = ImageType.ImageType2D;
                    option.Extent = new Extent3D(windowOption.Width, windowOption.Height, 1);
                    option.MipLevels = 1;
                    option.ArrayLayers = 1;
                    option.Samples = SampleCountFlags.SampleCount1Bit;
                    option.InitialLayout = ImageLayout.Undefined;
                    option.SharingMode = SharingMode.Exclusive;
                    if (props.LinearTilingFeatures.HasFlag(FormatFeatureFlags.FormatFeatureDepthStencilAttachmentBit))
                    {
                        option.Tiling = ImageTiling.Linear;
                        return true;
                    }
                    else if (props.OptimalTilingFeatures.HasFlag(FormatFeatureFlags.FormatFeatureDepthStencilAttachmentBit))
                    {
                        option.Tiling = ImageTiling.Optimal;
                        return true;
                    }
                    else return false;
                }, (option) =>
                {
                    option.Format = Format.D16Unorm;
                    option.Components = new ComponentMapping(ComponentSwizzle.R, ComponentSwizzle.G, ComponentSwizzle.B, ComponentSwizzle.A);
                    option.SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.ImageAspectDepthBit, 0, 1, 0, 1);
                    option.ViewType = ImageViewType.ImageViewType2D;
                });
                var pass = graphics.CreateSwapchainRenderPassFromConfiguration(lDevice, "main", swapchain, new Format[] { Format.D16Unorm });
                pass.ConfigBeginInfo((option) =>
                {
                    option.RenderArea = new Rect2D { Extent = new Extent2D(windowOption.Width, windowOption.Height), Offset = new Offset2D { X = 0, Y = 0 } };
                    option.ClearValues = new ClearValue[]
                    {
                    new ClearValue() { Color = new ClearColorValue(0.2f, 0.2f, 0.2f, 0.2f) },
                    new ClearValue() { DepthStencil = new ClearDepthStencilValue(1.0f, 0) }
                    };
                });
                pass.CreateSwapchainFrameBuffer(swapchain, new VulkanImageView[] { dImage }, windowOption.Height, windowOption.Width);
                var i = lDevice.CreateSemaphore(ArrangeConstant.ImageAvailableSemaphore);
                var f = lDevice.CreateSemaphore(ArrangeConstant.RenderFinishSemaphore);
                window.CreateVulkanRenderDispatcher(lDevice.WorkQueues[0], swapchain, pass, i, f);
            }
            catch (Exception e)
            {
                graphics.Logger.LogError(e.Message);
            }
            return Task.CompletedTask;
        }

        public void Initialization()
        {
        }
    }
}
